package com.yanxx.codegenerator.reset;

import com.yanxx.codegenerator.format.CodeFormatter;
import com.yanxx.codegenerator.format.impl.SimpleCodeFormatter;
import com.yanxx.codegenerator.impl.SequentialCodeGenerator;
import com.yanxx.codegenerator.storage.CodeGeneratorStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.Set;

/**
 * 可重置的编码生成器
 * 支持按照指定的重置策略（天、周、月）重置流水号
 */
public class ResettableCodeGenerator extends SequentialCodeGenerator {
    private static final Logger logger = LoggerFactory.getLogger(ResettableCodeGenerator.class);
    
    // 重置策略
    private final ResetStrategy resetStrategy;
    
    // 上次重置时间
    private LocalDateTime lastResetTime;
    
    // 存储器，用于持久化重置时间
    private CodeGeneratorStorage storage;
    
    /**
     * 构造函数
     *
     * @param startValue    起始编号值
     * @param formatter     编码格式化器
     * @param resetStrategy 重置策略
     */
    public ResettableCodeGenerator(long startValue, CodeFormatter formatter, ResetStrategy resetStrategy) {
        super(startValue, formatter);
        this.resetStrategy = resetStrategy;
        this.lastResetTime = LocalDateTime.now();
    }
    
    /**
     * 构造函数
     *
     * @param startValue    起始编号值
     * @param prefix        前缀
     * @param length        编号长度
     * @param resetStrategy 重置策略
     */
    public ResettableCodeGenerator(long startValue, String prefix, int length, ResetStrategy resetStrategy) {
        super(startValue, new SimpleCodeFormatter(prefix, length));
        this.resetStrategy = resetStrategy;
        this.lastResetTime = LocalDateTime.now();
    }
    
    /**
     * 构造函数，带存储器
     *
     * @param startValue    起始编号值
     * @param formatter     编码格式化器
     * @param resetStrategy 重置策略
     * @param storage       存储器
     */
    public ResettableCodeGenerator(long startValue, CodeFormatter formatter, ResetStrategy resetStrategy, CodeGeneratorStorage storage) {
        super(startValue, formatter);
        this.resetStrategy = resetStrategy;
        this.lastResetTime = LocalDateTime.now();
        this.storage = storage;
    }
    
    @Override
    public String generate() {
        checkAndResetIfNeeded();
        return super.generate();
    }
    
    @Override
    public void initialize() {
        super.initialize();
        this.lastResetTime = LocalDateTime.now();
        logger.info("Initialized ResettableCodeGenerator with reset strategy: {}", resetStrategy.getType());
    }
    
    /**
     * 检查是否需要重置，如果需要则执行重置操作
     */
    protected void checkAndResetIfNeeded() {
        LocalDateTime currentTime = LocalDateTime.now();
        if (resetStrategy.shouldReset(lastResetTime, currentTime)) {
            reset();
            this.lastResetTime = currentTime;
            logger.info("Reset code generator based on strategy: {}", resetStrategy.getType());
        }
    }
    
    /**
     * 重置生成器状态
     * 清空所有状态并将计数器重置为0
     */
    protected void reset() {
        // 获取当前状态
        Set<String> pendingCodes = getPendingCodes();
        Set<String> confirmedCodes = getConfirmedCodes();
        Set<String> recycledCodes = getRecycledCodes();
        
        // 清空所有集合
        pendingCodes.clear();
        confirmedCodes.clear();
        recycledCodes.clear();
        
        // 重置计数器
        setCurrentMaxValue(0);
        logger.debug("Reset generator state: cleared all codes and reset counter to 0");
        
        // 如果有存储器，保存重置状态
        if (storage != null) {
            storage.save(getCurrentMaxValue(), getConfirmedCodes(), getPendingCodes(), getRecycledCodes());
        }
    }
    
    /**
     * 获取上次重置时间
     *
     * @return 上次重置时间
     */
    public LocalDateTime getLastResetTime() {
        return lastResetTime;
    }
    
    /**
     * 设置上次重置时间
     *
     * @param lastResetTime 上次重置时间
     */
    public void setLastResetTime(LocalDateTime lastResetTime) {
        this.lastResetTime = lastResetTime;
    }
    
    /**
     * 获取重置策略
     *
     * @return 重置策略
     */
    public ResetStrategy getResetStrategy() {
        return resetStrategy;
    }
}